using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SCSEngine.Utils.Entities
{
    public class GameEntity : IGameEntity
    {
        private IDictionary<string, IGameComponent> components = new Dictionary<string, IGameComponent>();
        private IDictionary<Type, object> processes = new Dictionary<Type, object>();

        public bool AddComponent(IGameComponent component)
        {
            string componentName = component.GetType().FullName;

            return this.AddComponent(componentName, component);
        }

        public bool AddComponent(string componentName, IGameComponent component)
        {
            component.Initialize();
            if (!this.components.ContainsKey(componentName))
            {
                this.components.Add(componentName, component);
                return true;
            }
            else
            {
                this.components[componentName] = component;
                return false;
            }
        }

        public bool RemoveComponent(IGameComponent component)
        {
            string componentName = component.GetType().FullName;
            return this.RemoveComponent(componentName);
        }

        public bool RemoveComponent<GameComponent>() where GameComponent : IGameComponent
        {
            string componentName = typeof(GameComponent).FullName;
            return this.RemoveComponent(componentName);
        }

        public bool RemoveComponent(string componentName)
        {
            return this.components.Remove(componentName);
        }

        public GameComponent GetComponent<GameComponent>() where GameComponent : IGameComponent
        {
            string componentName = typeof(GameComponent).FullName;
            return this.GetComponent<GameComponent>(componentName);
        }

        public GameComponent GetComponent<GameComponent>(string componentName) where GameComponent : IGameComponent
        {
            if (this.components.ContainsKey(componentName))
            {
                return (GameComponent)this.components[componentName];
            }

            return default(GameComponent);
        }

        public IEnumerable<IGameComponent> Components
        {
            get { return this.components.Values; }
        }

        public bool AddProcess<Process>(object process)
        {
            if (process is Process)
            {
                if (this.processes.ContainsKey(typeof(Process)))
                {
                    this.processes.Add(typeof(Process), process);
                    return true;
                }
                else
                {
                    this.processes[typeof(Process)] = process;
                }
            }

            return false;
        }

        public bool RemoveProcess<Process>()
        {
            return this.processes.Remove(typeof(Process));
        }

        public Process GetProcess<Process>()
        {
            return (Process)this.GetProcess(typeof(Process));
        }

        public object GetProcess(Type processType)
        {
            if (this.processes.ContainsKey(processType))
            {
                return this.processes[processType];
            }
            
            return null;
        }

        public IEnumerable<object> Processes
        {
            get { return this.processes.Values; }
        }
    }
}
